在数据采集过程中,由于条件受限无法采集到数据,或者采集到的数据遗失了,出现了数据缺失,这就是缺失值。缺失值不是0,而是这个位置没有数据,是空的。数据中存在缺失值,会导致数据处理无法进行,所以必须先对缺失值进行处理,要么删除,要么用指定的值进行填充。[大谦Excel,dqexcel点com]
发现缺失值
【问题描述】
在给定的DataFrame中找出缺失值。
【示例9-3】
本例使用的Excel文件的完整路径为“D:/Samples/ch09/02 缺失值的处理/缺考人数.xlsx”。该文件打开后如图9-2所示,是某班学生的6门课的考试成绩。注意数据中有些位置没有数据,是空的,可能当时该同学缺考了。现在要求找出缺考的学生的学号和姓名,并汇总缺考的人数。
图9-2 学生考试成绩
- 编写下面的代码:
import pandas as pd
# 读取Excel文件中的第一个工作表,指定引擎为openpyxl
df = pd.read_excel(r"D:/Samples/ch09/02 缺失值的处理/缺考人数.xlsx", sheet_name=0, engine="openpyxl")
# 取前20行数据
df = df.head(20)
# 判断每个同学是否缺考(即至少有一门成绩缺失)
is_missing = df.isna().any(axis=1) # any函数用于判断每一行中是否有任意一个列是缺失值
missing_students = df[is_missing][["学号", "姓名"]] # 筛选出所有缺考同学的学号和姓名
# 统计缺考人数
num_missing_students = len(missing_students)
# 输出结果
print("缺考同学的学号和姓名:")
print(missing_students)
print("缺考同学的人数:", num_missing_students)
打开Python IDLE,新建一个脚本文件,将上面生成的代码复制进去,保存。运行脚本,在IDLE Shell窗口输出缺考同学的学号和姓名,以及缺考的人数。
>>> == RESTART: D:/Samples/1.py =
缺考同学的学号和姓名:
学号 姓名
4 150105 E
5 150106 F
7 150108 H
10 150111 K
15 150116 P
18 150119 S
缺考同学的人数: 6
【知识点扩展】
本例中,如果某行中至少有一个缺失值,即对应的学生至少缺考一门课,就认为该学生是缺考了的。下面的语句找到缺考学生的行索引。
is_missing = df.isna().any(axis=1)
其中,any函数用于判断每一行中是否有任意一个列是缺失值。
得到缺考学生的行索引后,用它们去索引df得到对应的行数据。
删除缺失值
【问题描述】
DataFame中的数据被发现是缺失值后,删除它们所在的行。
【示例9-4】
本例使用与示例9-3相同的数据。删除有缺失值的行。
- 编写下面的代码:
import pandas as pd # 导入pandas模块
# 使用pandas读取Excel文件的第一个工作表,只读取前20行,引擎为"openpyxl"
data = pd.read_excel("D:/Samples/ch09/02 缺失值的处理/缺考人数.xlsx", sheet_name=0, nrows=20, engine="openpyxl")
# 删除有缺失值的行
data.dropna(inplace=True)
# 输出修改后的表数据
print(data)
打开Python IDLE,新建一个脚本文件,将上面生成的代码复制进去,保存。运行脚本,在IDLE Shell窗口输出删除有缺失值的行后的数据。
>>> == RESTART: D:/Samples/1.py =
学号 姓名 语文 数学 英语 物理 化学 体育
0 150101 A 58.0 74 75.0 98.0 90.0 合格
1 150102 B 100.0 67 93.0 73.0 85.0 不合格
2 150103 C 0.0 96 66.0 58.0 0.0 合格
3 150104 D 76.0 91 89.0 50.0 95.0 合格
6 150107 G 78.0 61 90.0 82.0 94.0 不合格
8 150109 I 54.0 64 51.0 75.0 76.0 不合格
9 150110 J 50.0 66 88.0 63.0 93.0 合格
11 150112 L 50.0 89 92.0 73.0 54.0 不合格
12 150113 M 77.0 89 0.0 70.0 79.0 不合格
13 150114 N 82.0 95 77.0 62.0 66.0 合格
14 150115 O 60.0 93 95.0 85.0 78.0 不合格
16 150117 Q 53.0 95 51.0 97.0 92.0 不合格
17 150118 R 58.0 64 50.0 60.0 70.0 合格
19 150120 T 85.0 86 92.0 69.0 61.0 合格
【知识点扩展】
使用DataFrame对象的dropna方法直接删除有缺失值的行。
填充缺失值
【问题描述】
直接删除有缺失值的行会损失一部分有用信息,所以处理缺失值的另一种常用方法是用特定的值填充缺失值。
【示例9-5】
本例使用与示例9-3相同的数据。用缺失值上面的值填充缺失值。
- 编写下面的代码:
import pandas as pd
# 读取Excel文件中的数据(前20行),引擎为openpyxl
data = pd.read_excel("D:/Samples/ch09/02 缺失值的处理/缺考人数.xlsx", sheet_name=0, engine="openpyxl", nrows=20)
# 用缺失值上面的值填充缺失值
data.fillna(method='ffill', inplace=True)
# 输出修改后的表数据
print(data)
打开Python IDLE,新建一个脚本文件,将上面生成的代码复制进去,保存。运行脚本,在IDLE Shell窗口输出填充缺失值后的数据。
>>> == RESTART: D:/Samples/1.py =
学号 姓名 语文 数学 英语 物理 化学 体育
0 150101 A 58.0 74 75.0 98.0 90.0 合格
1 150102 B 100.0 67 93.0 73.0 85.0 不合格
2 150103 C 0.0 96 66.0 58.0 0.0 合格
3 150104 D 76.0 91 89.0 50.0 95.0 合格
4 150105 E 55.0 68 89.0 99.0 97.0 不合格
5 150106 F 58.0 78 97.0 53.0 51.0 不合格
6 150107 G 78.0 61 90.0 82.0 94.0 不合格
7 150108 H 78.0 51 0.0 84.0 64.0 不合格
8 150109 I 54.0 64 51.0 75.0 76.0 不合格
9 150110 J 50.0 66 88.0 63.0 93.0 合格
10 150111 K 85.0 0 85.0 50.0 93.0 合格
11 150112 L 50.0 89 92.0 73.0 54.0 不合格
12 150113 M 77.0 89 0.0 70.0 79.0 不合格
13 150114 N 82.0 95 77.0 62.0 66.0 合格
14 150115 O 60.0 93 95.0 85.0 78.0 不合格
15 150116 P 60.0 73 95.0 84.0 74.0 不合格
16 150117 Q 53.0 95 51.0 97.0 92.0 不合格
17 150118 R 58.0 64 50.0 60.0 70.0 合格
18 150119 S 58.0 89 92.0 60.0 70.0 合格
19 150120 T 85.0 86 92.0 69.0 61.0 合格
【知识点扩展】
使用DataFrame对象的fillna方法填充缺失值。用method参数指定填充的方法,比如值为”ffill”时用前一个值填充,值为”bfill”时用后一个值填充。用value参数可以将缺失值指定为一个固定的值。